/**
 * 
 */
package abstractions;

import interfaces.EMUW;
import emu.EMU;

import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;


/**
 * @author rdru
 * INV: 
 */
public class EditingDoc extends OpenDoc {	// used by the Client
	LinkedList<Atom>					atoms;		// the representation of a doc
	Pos									cp;			// current position
	Selection							cs;			// current selection
	public boolean						isDirty;	// state info
	LinkedList<Command>					histNew;
	LinkedList<Command>					undo;
	public LinkedList<EMUW>				winList;	// where this EMUDoc is shown
	public HashMap<AtomId, Atom>		id2atom;	// HashMap to speed AtomId to Atom
	
	// constructor
	public EditingDoc(Doc d, String text, EMUW win) throws RemoteException {
		super(d, text);
		createAtomsFromText();					// init the atoms list with text
		cp = new Pos(atoms.getFirst(), 0);
		cs = null;
		isDirty = false;
		histNew = new LinkedList<Command>();
		undo = new LinkedList<Command>();
		winList = new LinkedList<EMUW>();
		id2atom = new HashMap<AtomId, Atom>(200);	// initialCapacity should be defined at Constants.java
	}
	
	public EditingDoc(String pathName, boolean isRemote) {
		// open the file, get the parameters and call
		EditingDoc(d, text, EMU.cw);
		//>>>
	}
	// parse the text, setup each Atom and insert them into atoms.
	void createAtomsFromText() {
		int id = 1;
		for (String s: text.split("\n"))
			atoms.addLast(new Atom(new AtomId(new ArrayList<Integer>(id++)), 0, s));
	}

	public void setText(String text) {
		this.text = text;
	}
		
	// add a new Window to the list of Windows for this EMUDoc
	void addWin(EMUW win) {
		winList.add(win);
	}

	public void closeDoc() {
		if (isRemote) {
			// sends all recent comands to the Server
		
		} else 
			if (isDirty) {
				@SuppressWarnings("unused")
				String texto = this.toString();
			
				// salva arquivo
			
		}
		// close (removes this from the doc and win lists
		
	}

	// returns the text of the document
	public String toString() {
		StringBuilder s = new StringBuilder();
		for (Atom a: atoms)
			s.append(a.at);
		return s.toString();
	}
	
	
	// ********************** Methods called by the server
	
	public void addNewUpdate(CommandC[] cmds) {
		histOld.addAll(cmds);
	}
	
	// ********************** Metods indirectly called by the Server
	
	// Locks the atomId to userId
	void lockAtom(int serverId, int docId, AtomId aId, int userId) {}

	// Unlocks the atomId
	void unlockAtom(int serverId, int docId, AtomId aId) {}

	// Add an user to the userList
	void addClientToDoc(int serverId, int docId, int userId) {}

	// Remove an user from the userList
	void removeClientFromDoc(int serverId, int docId, int userId) {}


	
	// ********************** Editing the EMUDoc

	// This methods are called in response to user actions on the editing window which
	// can be of 2 forms: menu commands (cut, copy, paste, select all, ...) and
	// direct editing actions on the text window (events captured at that window).

	// Retorna o Atom posterior a a na atomList
	Atom next(Atom a) {
		return null;		// to compile ...
	}

	// Retorna o Atom anterior a ana AtomList
	Atom prev(Atom a) {
		return null;		// to compile ...
	}
	
	// Insere uma part a partir de pos
	void insertP(Part p, Pos pos) {}

	// Insere o ClipBoard do usuario, Part pode ser composta pelo conteudo de varios
	// Atom e no comeco e no fim por pedacos de conteudo de Atom.
	void setClipBoard(Part p) {}

	// Remove n caracteres a frente se n>0, remove -n caracteres atras se n<0
	void del(Pos pos, int n) {}

	// guarda selecao no clipboard
	public void copy() {}

	// Seleciona um intervalo (co,cc) a (ca1,cc1). Apos o uso (ca1,cc1).
	void setSelection(Pos l) {}

	// Remove a selecao e guarda no clipboard
	public void cut() {}

	// insere conteudo do clipboard na posicao do cursor
	public void paste() {}

	// Cria um Atom e insere o antes do Atom dado.
	Atom newAtomBefore(AtomId aid) {
		return null;		// to compile ...
	}

	// Cria um Atom e insere depois do Atom dado.
	Atom newAtomAfter(AtomId aid) {
		return null;		// to compile ...
	}

	// remove do EMUDoc o Atom passado
	void delAtom(AtomId aid) {}

	// divide o Atom a em dois Atoms (a, b) na posicao p.
	// Retorna o Atom b
	Atom splitAtom(AtomId aid, Pos p) {
		return null;		// to compile ...
	}

	// Une dois Atom em um novo Atom que retem a AtomId de a.}
	void joinAtom(AtomId aid, AtomId b) {}

	// Creates a copy of the
	Part copy(Selection sel) {
		return null;		// to compile ...
	}

	// Remove a Part correspondente a curSelection e NAO armazena no clipBoard.
	void del(Selection sel) {}

	// Remove a Part correspondente a curSelection e armazena no clipBoard.
	void cut(Selection sel) {}

	// Insere na curPos a Part p.
	void paste(Part p) {}

	// set the current selection.
	void setSelection(Pos p1, Pos p2) {}

	//
	public void selectAll() {
		setSelection(new Pos(atoms.getFirst(), 0), new Pos(atoms.getLast(), atoms.getLast().at.length()));
	}
	
	// 
	public void undo() {
	}
	
	// 
	public void redo() {
	}

}
